package com.powerfl.frm.taf{
	
	import flash.display.*;
	import flash.events.*;
	import flash.geom.*;
	import flash.ui.Mouse;
	import flash.ui.MouseCursor;
	import flash.utils.*;
	
	final internal class TAFbitmapBlit extends Bitmap{
		
		internal var _rect:Rectangle;
		internal var _isUpdated:int;
		public var _width:Number;
		public var _height:Number;
		
		private var _names:Object;
		private var _children:Vector.<TAFbitmapBlitChild>;
		
		internal var _depthData:BitmapData;
		private var _depthKey:uint;
		private var _depth:Array;
		
		public var ownCanvas:Boolean = true;
		
		public var _over:Dictionary;
		public var _out:Dictionary;
		public var _down:Dictionary;
		public var _up:Dictionary;
		
		private var _prevTarget:TAFbitmapBlitChild;
		private var _currentTarget:TAFbitmapBlitChild;
		private var _mouseX:Number;
		private var _mouseY:Number;
		
		
		public function TAFbitmapBlit(){
			smoothing = true;
		}
		internal function init():void{
			bitmapData = TAF.SELF.bitmapData( _width, _height );
			width = bitmapData.width;
			height = bitmapData.height;
			_rect = bitmapData.rect;
			_children = new Vector.<TAFbitmapBlitChild>();
			_names = {};
			
			_depthData = bitmapData.clone();
			_depthKey = 0xff000000;
			_depth = [];
			
			_over = new Dictionary( true );
			_out = new Dictionary( true );
			_down = new Dictionary( true );
			_up = new Dictionary( true );
			
			_isUpdated = 0;
		}
		internal function render():void{
			var i:int, j:int, key:*;
			key = 0;
			if( _isUpdated < 0 ){
				key = -1;
			}else{
				for( i = 0, j = _children.length ; i < j ; ++i ){
					if( _children[i].isUpdate() < 0 ){
						key = -1;
						break;
					}
				}
			}
			_currentTarget = get();
			if( _currentTarget === _prevTarget ){
			}else{
				if( _prevTarget ){
					for each( key in _out[_prevTarget] ){
						key();
					}
					_prevTarget = null;
				}
				if( _currentTarget ){
					if( _currentTarget.useHandCursor ){
						Mouse.cursor = MouseCursor.BUTTON;
					}
					for each( key in _over[_currentTarget] ){
						key();
					}
					_prevTarget = _currentTarget;
				}else{
					Mouse.cursor = MouseCursor.ARROW;
				}
			}
			if( key < 0 ){
				bitmapData.lock();
				_depthData.lock();
				bitmapData.fillRect( _rect, 0 );
				_depthData.fillRect( _rect, 0 );
				for( i = 0, j = _children.length ; i < j ; ++i ){
					_children[i].render();
				}
				bitmapData.unlock();
				_depthData.unlock();
				_isUpdated = 0;
			}
		}
		public function get numChildren():uint{
			return _children.length;
		}
		internal function down():void{
			var key:*;
			for each( key in _down[get()] ){
				key();
			}
		}
		internal function up():void{
			var key:*;
			for each( key in _up[get()] ){
				key();
			}
		}
		private function get():TAFbitmapBlitChild{
			_mouseX = TAF.STAGEX - x;
			_mouseY = TAF.STAGEY - y;
			if( _mouseX > -1 && _mouseY > -1 ){
				return _depth[_depthData.getPixel32( _mouseX, _mouseY )];
			}else{
				return null;
			}
		}
		internal function addChild( $child:TAFbitmapBlitChild ):void{
			$child.init( this, _depthKey );
			_depth[_depthKey] = $child;
			_children[_children.length] = $child;
			++_depthKey;
			_isUpdated = -1;
		}
		internal function removeChild( $child:TAFbitmapBlitChild ):void{
			_depth[$child.depth] = null; 
			_children.splice( _children.indexOf( $child ), 1 );
			_isUpdated = -1;
		}
	}
}